package contable.dominio;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Un registro realizado y su descripción
 *
 * @author jaime
 */
public class Registro {

    private Date fecha;
    private String descripcion;
    private double saldo;
    private Periodo periodo;
    private Cuenta cuentas[];
    private int idx;

    /**
     * Constructor genérico
     */
    public Registro() {
        idx = 0;
        cuentas = new Cuenta[2];
    }

    /**
     * Constructor especializado
     * @param fecha la fecha y hora en que se realizo el registro
     * @param descripcion La descripción del registro
     * @param saldo El saldo del registro
     * @return El periodo contable del registro
     * @param cuentas Las cuentas incluidas en el registro
     */
    public Registro(Date fecha, String descripcion, double saldo, Periodo periodo, Cuenta... cuentas) {
        setFecha(fecha);
        setDescripcion(descripcion);
        setSaldo(saldo);
        setPeriodo(periodo);
        this.cuentas = cuentas;
        idx = cuentas.length;
    }

    /**
     * Obtener la fecha y hora en que se realizo el registro
     *
     * @return La fecha y hora del registro
     */
    public Date getFecha() {
        return fecha;
    }

    /**
     * Establecer la fecha y hora en que se realizo el registro
     *
     * @param fecha la fecha y hora en que se realizo el registro
     */
    public final void setFecha(Date fecha) {
        if (fecha == null) {
            throw new IllegalArgumentException("La fecha y hora del registro no puede ser vacia");
        } else {
            this.fecha = fecha;
        }
    }

    /**
     * Obtener la descripción de que trata el registro
     *
     * @return La descripción del registro
     */
    public String getDescripcion() {
        return (descripcion == null) ? "" : descripcion;
    }

    /**
     * Establecer la descripción de que trato el registro
     *
     * @param descripcion Descripción del registro
     */
    public final void setDescripcion(String descripcion) {
        this.descripcion = descripcion;
    }

    /**
     * Obtener el valor con el que se hizo el registro
     * @return El saldo del registro
     */
    public double getSaldo() {
        return saldo;
    }

    /**
     * Establecer el saldo del registro realizado
     *
     * @param saldo El saldo del registro
     */
    public final void setSaldo(double saldo) {
        if (saldo < 0) {
            throw new IllegalArgumentException("El saldo del registro no puede ser negativo");
        } else {
            this.saldo = saldo;
        }
    }

    /**
     * Obtener el periodo contable en que se realizo el registro
     * @return El periodo contable del registro
     */
    public Periodo getPeriodo() {
        return periodo;
    }

    /**
     * Establecer el periodo en que se realizo el registro
     *
     * @param periodo El periodo en que se realizo el registro
     * @see contable.dominio.Periodo
     */
    public final void setPeriodo(Periodo periodo) {
        this.periodo = periodo;
    }

    /**
     * Añadir una cuenta afectada al registro
     *
     * @param cuenta La cuenta afectada
     */
    public void addCuenta(Cuenta cuenta) {
        if (idx < cuentas.length) {
            cuentas[idx] = cuenta;
            idx++;
        } else {
            Cuenta[] tmp = cuentas;
            cuentas = new Cuenta[idx + 1];
            System.arraycopy(tmp, 0, cuentas, 0, tmp.length);
            addCuenta(cuenta);
        }
    }

    /**
     * Obtener la cuentas afectadas por el registro
     *
     * @return Las cuentas afectadas
     */
    public Cuenta[] getCuentas() {
        return cuentas;
    }

    @Override
    public String toString() {
        SimpleDateFormat format = new SimpleDateFormat("dd MMMM 'de' yyyy 'a las' HH:mm:ss");
        String r = "Fecha y hora: " + format.format(fecha)
                + "\nDescripción: " + descripcion
                + "\nSaldo: $" + saldo
                + "\n" + periodo + "\nCuentas afectadas: ";
        for (Cuenta cuenta : cuentas) {
            r += cuenta;
        }
        return r;
    }
}
